import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

/**
 *  编写代码, 实现定时器案例
 */

class MyTask implements Comparable<MyTask>{

    // 重写 compareTo 方法.
    @Override
    public int compareTo(MyTask o) {
        return (int) (this.time - o.time);
    }

    // 什么时候执行(time是一个时间戳)
    private final long time;
    // 执行的具体任务
    private final Runnable runnable;

    MyTask(Runnable runnable, long delay) {
        this.time = System.currentTimeMillis() + delay;
        this.runnable = runnable;
    }

    public long getTime() {
        return this.time;
    }

    public Runnable getRunnable() {
        return this.runnable;
    }
}

class MyTimer {
    // 优先级阻塞队列.
    private final BlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();

    private final Object object = new Object();

    public MyTimer()  {
        // 创建一个 扫描进程.
       Thread t = new Thread(() -> {
          while(true) {
              try {
                  synchronized (object) {
                      MyTask task = queue.take();
                      long curTime = System.currentTimeMillis(); //记录当前时间.
                      if(curTime >= task.getTime()) {
                          // 到时间了, 执行任务
                          task.getRunnable().run();
                      } else {
                          queue.put(task); //时间没到 将该任务放回队列中.
                          object.wait(task.getTime() - curTime);
                      }
                  }
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
       });
        t.start();
    }

    public void schedule (Runnable runnable, long time) throws InterruptedException {
        // 将定时器安排的任务放到优先级阻塞队列中.
        MyTask myTask = new MyTask(runnable,time);
        queue.put(myTask);
        synchronized (object) {
            object.notify();
        }
    }
}
public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        MyTimer myTimer = new MyTimer();

        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("1s后执行任务");
            }
        },1000);

        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("0.5s后执行任务");
            }
        },500);

        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("2s后执行任务");
            }
        },2000);

        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("1.5s后执行任务");
            }
        },1500);
    }
}
